Skip to content

fix(extractor): reject unresolved structural styling inputs - #791

Open
owjs3901 wants to merge 9 commits into
mainfrom
fix/unresolved-global-inputs
Open

owjs3901 wants to merge 9 commits into
mainfrom
fix/unresolved-global-inputs

Conversation

@owjs3901

@owjs3901 owjs3901 commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Refs #791 (coverage 보강 2c5e520; MAIN SETTLED 81d6d92 반영, #893 포함 settled main 추가 반영 후 최종 완료)

요약

빌드가 읽을 수 없는 global imports/fonts/selector params를 located error로 거부하는 기존 목적을 유지하면서, 최신 main의 authored-order Projection과 StyleInputs absence proof를 함께 보존했습니다. 검증된 snapshot의 strict params, iterative metadata/capture/Plan bridge, compositional target 및 placement ownership을 그대로 통합했으며, 스타일링 런타임이나 새 dependency는 추가하지 않았습니다.

동작

  • 전역 imports, fontFaces, selector params는 빌드가 증명할 수 있는 정적 입력만 출력하고, 읽을 수 없는 입력은 원래 위치의 build error로 남깁니다.
  • 순수 URL/import 및 정적 font descriptor/template은 기존 CSS와 dependency 순서를 유지합니다. optional undefined/null은 proven absence일 때만 생략합니다.
  • nested selectors, conditional/logical expressions, responsive arrays, computed members와 lowered JSX 경로에 StyleInputs와 LOCATE 정책을 함께 전달합니다.
  • #798의 quoted selector handling, strict comparisons, metadata-preserving clones, const-object extraction과 #791의 font terminal veto 및 values_run.is_none() 계약을 유지합니다.
  • build-time extractor만 변경했으며 emitted runtime helper/import/evaluator/schema는 추가하지 않았습니다.

새로 생기는 오류

이번 coverage 보강은 새 build error를 추가하지 않으며 아래 기존 dense-params 계약을 유지합니다.

  • 일반 추출의 HELPERS.literal JSON 경로에서 helper가 계산한 params 배열은 dense여야 합니다. JSON이 hole/null/undefined를 같은 null 표현으로 바꾸므로 이 경로의 세 값은 구분할 수 없고, supplying helper 호출 위치의 build error로 거부합니다. workaround는 return ['a', 'b']처럼 빈 칸/null/undefined 없는 dense 배열을 반환하는 것입니다. serializer 자체를 새로 바꾸거나 다른 값 문맥에 이 제한을 넓히지 않았습니다.
  • authored literal 배열과 native Boa stylesheet capture처럼 실제 배열을 보는 경로는 hole skipping과 presence 의미를 유지합니다. own/inherited undefined는 거부하고 inherited defined 값은 기존처럼 읽습니다. 오류 owner는 ordinary/lossy helper 경로에서는 공급 helper 호출, native stylesheet capture에서는 실제 css() 호출입니다. 둘을 같은 위치라고 표현하지 않습니다.
  • params 원소의 객체·중첩 배열 같은 container는 정적인 인수로 암묵 변환하거나 toJSON으로 올바른 모양인 것처럼 바꾸어 허용하지 않고 거부합니다. 원래 인수와 위치를 남깁니다.
  • 깊은 bridge 경로의 명시적 빈 params 10개를 바로잡았습니다. :hover/:host 각각 []와 ['']는 괄호 없는 bare selector (4개), :nth-child/::part/:is 각각 []와 ['']는 required-argument build error (6개)입니다. params 속성 자체가 생략된 모든 문법 문제를 해결했다고 주장하지 않습니다.

다음처럼 구조를 빌드 타임에 알 수 없는 입력은 조용히 누락되거나 부분 CSS로 남지 않고 파일:행:열 오류가 됩니다.

globalCss({ imports: [{ url: unknownUrl }] })
globalCss({ imports: [{ url: 'base.css', query: tick() }] })
globalCss({ fontFaces: [{ ...unknownDescriptors, src: 'face.woff2' }] })
globalCss({ fontFaces: [`font-family: ${unknownFamily};`] })
<Box _nthChild={{ params: ['2n', unknownParam], color: 'red' }} />

남는 한계

동일한 작은 authored selector 입력이 main 81d6d924에서도 기본 스택을 넘는 기존 오류를 별도로 재현했습니다. 원본 입력과 기대 결과를 보존해 forward item 3의 main 기반 failing-first 수정으로 분리했으며, 이 PR에서 고쳤다고 주장하거나 스택 확대로 해결하지 않습니다.

별도로 제외된 main-only params 문법 4개는 여전히 미수정입니다: :hover에 params:['','x']가 :hover(x)를 만드는 경우와 params 속성 자체를 생략한 bare :nth-child / ::part / :is입니다. 위의 10개 명시적 deep-empty correction과 혼동하지 않습니다. 기존 overridden alias atom 후속도 이 PR의 완료 범위에 넣지 않습니다.

빌드에서 증명할 수 없는 import/font descriptor/selector 인수는 정적인 표현식으로 바꾸어야 합니다. 일반 동적 element 값의 기존 CSS-variable 경로, selector cascade order, evaluator의 기존 지원 범위는 변경하지 않았습니다. ReferenceError, spread/eager-order, theme located-error, key-coercion, Windows PID 후속 수정은 별도 PR로 진행합니다.

검증

Coverage 보강 현재 head (2026-11-01)

  • coverage 전용 commit 2c5e52074821871237666a2059d9ee1de470df50, tested/staged/committed tree 5810ac35cce97c3c0c23564bf569fdd00ec0fcd2, 실제 parent **0c1aef00**입니다. main merge와 섞지 않았습니다. #893을 포함한 settled main은 이후 별도 true merge로 반영해야 합니다.
  • accessor/spread params의 실제 평가와 getter 횟수, media/layer requiredness, native Join/pop/cache 및 lexical suffix, BigInt/Infinity의 terminal located error, 실제 capture 배열 순서, layer 이름 props의 invalid-root refusal과 올바른 LayerOrder를 회귀 테스트로 검증했습니다.
  • 외부 역할 match가 배제하는 Styles fallback 2곳과 항상 초기화되던 Item/Unknown tail의 cache-miss fallback 2곳은 역할별 dispatch와 직접 tail/Join 전용 지연 캐시로 표현했습니다. 분석 전용 불확실성은 cached requiredness만 보유하고 렌더 Frame을 만들지 않습니다. panic, coverage 제외, threshold 변경은 없습니다.
  • frozen 3bda73f0 대비 추가 production ledger 1007 changed lines / 12 paths / 새 2 paths는 이 coverage unit에 승인된 1010 이내입니다. 두 serializer 파일은 baseline과 동일하며 폐기한 contextual serializer를 되살리지 않았습니다.
  • default stack의 직접 관찰에서 memoized Join tail은 두 CSS 모드 각각 성공 경로 2회, required-error 경로 1회 실행됐습니다. 임시 marker는 raw byte/index/tree/diff까지 정확히 복원한 뒤 최종 staging했습니다. 남은 required target을 버리면 거부 회귀 테스트가 실패합니다.
  • 최종 fmt/strict all-targets/all-features clippy/TS6-preload ESLint, focused 383/0, public WASM 18/18 + 36회 byte-repeat 비교가 통과했습니다. Window 83의 default-stack workspace 11,647/0 (--jobs1) 및 fresh WASM/root/dist는 동작/순서/할당이 같은 as_slice와 compile-time concat 보정에 대해 명시적으로 재사용 승인됐습니다. 빌드가 수정 후 source-byte 동일하다고 주장하지 않습니다.
  • ONE 정상 hook / ONE coverage commit / ONE push. hook 921.289초, Rust 11,647/0, root 6,767/0, Vite 872/0, 양쪽 All files 실제 100.00% functions / 100.00% lines. Windows Rust **97.81% (32517/33245)**는 참고값입니다. 새 snapshot 생성/승인은 없습니다.
  • 정확한 head의 CI 41305680419 FAILURE. Linux Rust **100% (22785/22785)**를 정확한 head의 publish 로그에서 확인했습니다.
  • landing-next-e2e: failure / webpack-extends-theme: success / deploy-pages: skipped / publish: success / wasm-size: success / release-compat: success / vinext-rsc-css-e2e: success / react-18: success / benchmark: success / release: skipped. 전체 CI green이 아닙니다. pre-fix(ci): stabilize landing dev GitHub requests #893 Next dev-navigation API 403의 허용된 job rerun 1회도 사용했으며 추가 rerun하지 않습니다.

이전 통합 head 0c1aef00의 역사적 검증 (현재 coverage head의 증거가 아님)

  • 검증된 snapshot **fdee66c2 / tree 18ada831**와 공지된 MAIN SETTLED **81d6d924**의 merge-tree에는 새 충돌이 없었습니다. 실제 merge 상태에서 기존 6개 source 충돌을 그 검증된 결과로 복원했고, HEAD 0c1aef00a53cd8de1c3bff6c413433e8e96b17fd, tree a5bea69e2bae4611d1338c5fe02c0d7b3b78f551, 실제 parent **71bfbad7 + 81d6d924**를 확인했습니다.
  • libs/bindings/Cargo 등 1453개 개별 경로의 mode/blob가 검증된 tree와 모두 동일합니다. 추가 통합 수리의 승인된 ledger는 frozen 3bda73f0 대비 production 999 changed lines / 12 paths / 새 production paths 2개 그대로입니다. 이는 main 대비 전체 PR 크기를 뜻하지 않습니다. build_time_values.rs와 build_time_values_execute.rs는 frozen baseline과 정확히 같고, 폐기한 contextual serializer를 되살리지 않았습니다.
  • Bun 1.4.4, Node 26.12.0, default Rust stack, CI unset, jobs2. frozen install 1191 installs / 1433 packages, no changes, fresh WASM/root build/verify:dist, fmt/strict clippy/TS6-preload ESLint 통과했습니다. source equality를 근거로 별도 standalone Rust 및 Bun coverage 중복 실행은 승인된 trim에 따라 생략했고, 정상 hook이 이를 다시 실행했습니다. 이전 validated workspace 11,603/0, --jobs1 증거와 이번 hook의 default-stack 11,603/0을 구분합니다.
  • fresh-prefix public WASM QA 76/76, 매번 byte-repeat 비교, 두 CSS 모드의 8개 params-omitted control에서 code/CSS/dependencies 완전 동등성을 확인했습니다. 선택된 class의 cascade 최종값은 16px이며, 양쪽 모두 남아 있는 overridden 12px atom은 기존 main follow-up (f)이지 이번 PR의 수정이 아닙니다. 새 insta snapshot 생성/승인은 없습니다.
  • Window 73에서 ONE 정상 hook / ONE push, hook 889.005초, peak 6,567,628,800 bytes (12 GB 상한), heartbeat 실패 0, owned job empty/closed. hook root 6,767/0, Vite 872/0, 양쪽 실제 All files 100.00% functions / 100.00% lines. Windows Rust **97.74% (32491/33243)**는 Linux 100%라고 표현하지 않습니다. exact tested/staged/committed tree와 두 parent, clean 작업 트리를 확인했습니다.
  • hook 직전 origin/main을 다시 fetch하고 inbox를 확인했으며 81d6d92 / 새 settled announcement 없음이었습니다. hook은 07:53:44 UTC에 시작했습니다. #893을 포함한 새 settled main이 공지되면 추가 true merge 후 최종 완료할 예정이며, 아직 그 반영을 완료했다고 주장하지 않습니다.
  • 정확한 head 0c1aef00a53cd8de1c3bff6c413433e8e96b17fd의 CI 41287680944 FAILURE, attempt 1. benchmark: success / landing-next-e2e: success / publish: failure / webpack-extends-theme: success / wasm-size: success / react-18: success / vinext-rsc-css-e2e: success / release-compat: success.
  • 당시 publish는 Linux Rust coverage 99.89% (22766/22792), 26 uncovered lines 때문에 실패했으며 전체 CI green이 아닙니다. 나머지 7개 validation job은 통과했습니다. 그 당시 coverage map과 실제 동작을 검증할 test plan을 작성했지만 아직 테스트/production 수정, rerun 또는 추가 commit/push는 하지 않았습니다. 이전 Windows 정상 hook이나 byte-equality receipt를 Linux 100%로 간주하지 않습니다.

이전 제출 및 통합의 역사적 검증 (아래 수치는 현재 head의 증거가 아님)

  • 실제 second-merge commit: 38e7ac2e24f0f66eec84683d7dc2d56ba8eb760e; tree ebabb6411b5b6f7f94d8cbdfb71ff8a9b1b89e4f; parents 정확히 69a5286317fb7cc8babb34ec1ed17c61ed9acab6 + 78d7c2b2673bdeaa0870bac6a2ec424706986de7.
  • fresh bun install, binding WASM build, root build, Rust 1.99 strict clippy, default-stack cargo test --workspace 통과. Workspace 결과는 extractor 5,719 pass 및 전체 0 fail입니다.
  • bun run test: 6,654 pass, 0 fail, 89 snapshots; 실제 All files 함수/라인 100.00/100.00.
  • bun lint: 0 errors, inherited React 19 warning 20건만 존재합니다. exact-tree hook은 한 번 PASS했습니다. Windows LLVM tarpaulin 참고값은 97.87%이며 Linux coverage 증명으로 사용하지 않습니다.
  • fresh public WASM/React QA는 per-file 및 single-CSS 46/46 pass, deterministic output과 effect trace 0을 확인했습니다. fresh shipped-name audit는 matches: []입니다.
  • independent staged-tree review는 PASS, findings 없음입니다. conflict marker와 runtime addition은 확인되지 않았습니다.
  • matching CI 39623046266 SUCCESS: publish, react-18, wasm-size, benchmark, release-compat, landing-next-e2e, vinext-rsc-css-e2e, webpack-extends-theme 모두 통과했습니다. publish job의 Linux Rust 100% 및 Bun All files 100% gate가 통과했습니다.

새로운 runtime 동작이나 dependency는 없습니다. CI의 Node.js 20 deprecation/ubuntu-latest migration 안내는 workflow 경고이며 실패가 아닙니다.

과거 main 병합 검증 (d121976)

  • main d1219765를 두 부모를 갖는 merge commit으로 통합했습니다(rebase 없음).
  • style_values.rs: PR의 absence 모듈과 main의 공유 lexical scoping을 모두 유지했습니다. visit.rs: main의 scoping 재사용/compiled-read 진단/StyleX 예약과 PR의 absence 기록을 결합하고, factory 재귀 처리에는 별도 absence proof를 전달합니다.
  • extract_style_from_expression.rs 및 extract_style_from_member_expression.rs: PR의 StyleInputs 전달과 main의 semantic-ID 보존 clone 및 동적 값 prepare callback을 함께 유지했습니다. 기존 테스트/assertion을 보존하고, absent selector params와 중첩 css factory를 결합한 회귀 테스트를 두 CSS 모드에서 실패 재현 후 통과시켰습니다.
  • WASM/전체 빌드, fmt, clippy, Rust 전체 테스트 통과. Bun 6,248개 및 Vite 868개 테스트 실패 0개, 각각 All files | 100.00 | 100.00 |. hook 전체 통과; lint 오류 0개(기존 경고 20개).

Refs #686

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@codecov

codecov Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Files with missing lines Coverage Δ
libs/css/src/lib.rs 100.00% <ø> (ø)
libs/css/src/selector_params.rs 100.00% <100.00%> (ø)
libs/extractor/src/dead_properties/calls.rs 100.00% <100.00%> (ø)
libs/extractor/src/dead_properties/params.rs 100.00% <100.00%> (ø)
.../extractor/extract_global_style_from_expression.rs 100.00% <100.00%> (ø)
...src/extractor/extract_keyframes_from_expression.rs 100.00% <100.00%> (ø)
...tor/src/extractor/extract_style_from_expression.rs 100.00% <100.00%> (ø)
.../extractor/src/extractor/extract_style_from_jsx.rs 100.00% <100.00%> (ø)
.../extractor/extract_style_from_member_expression.rs 100.00% <100.00%> (ø)
...tractor/src/extractor/extract_style_from_styled.rs 100.00% <100.00%> (ø)
... and 25 more
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

owjs3901 and others added 4 commits October 20, 2026 12:06
Refs #686

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #686

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #686

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #791

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
owjs3901 and others added 2 commits October 23, 2026 22:57
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Archibald1948 pushed a commit to Archibald1948/devup-ui that referenced this pull request Oct 30, 2026
Refs dev-five-git#791

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
owjs3901 and others added 2 commits November 1, 2026 16:53
Refs #791

Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Refs #791

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant